'''
陈超依 19377189
现代程序设计第五次作业
'''

from os import error
import jieba
import random #用于测试
from matplotlib import pyplot as plt  #用于测试

class Tokenizer:
    def __init__(self, chars : list, coding='c', PAD=0):
        self.chars = chars
        if (coding not in ['c', 'w']):
            return error
        self.coding = coding
        if (PAD > 0):
            return error
        self.PAD = PAD
        self.TokDict = {}
        self.TokDict['[PAD]'] = self.PAD
        if (self.coding == 'c'):
            for EachSen in self.chars:
                Lcha = list(EachSen)
                for EachCha in Lcha:
                    if (EachCha in self.TokDict):
                        continue
                    order = len(self.TokDict)
                    self.TokDict[EachCha] = order
        if(self.coding == 'w'):
            for EachSen in self.chars:
                Lcha = jieba.lcut(EachSen)
                for EachCha in Lcha:
                    if(EachCha in self.TokDict):
                        continue
                    order = len(self.TokDict)
                    self.TokDict[EachCha] = order
    def tokenize(self, sentence : str):
        if (self.coding == 'c'):
            Lcha = list(sentence)
        if (self.coding == 'w'):
            Lcha = jieba.lcut(sentence)
        return Lcha
    def encode(self, list_of_cha : list):
        result = []
        for i in range(len(list_of_cha)):
            result.append(self.TokDict[list_of_cha[i]])
        return result
    def trim(self, tokens : list, seq_len : int):
        if(len(tokens) > seq_len):
            return tokens[:seq_len]
        result = tokens[:]
        for i in range(seq_len - len(tokens)):
            result.append(self.PAD)
        return result
    def decode(self, tokens : list):
        ReDict = {v:k for k,v in self.TokDict.items()}
        result = []
        for EachCha in tokens:
            result.append(ReDict[EachCha])
        return result
    def encode_all(self, seq_len : int):
        result = []
        if (self.coding == 'c'):
            for EachSen in self.chars:
                Lcha = list(EachSen)
                if (len(Lcha) == seq_len):
                    result.append(EachSen)
        if(self.coding == 'w'):
            for EachSen in self.chars:
                Lcha = jieba.lcut(EachSen)
                if (len(Lcha) == seq_len):
                    result.append(EachSen)
        return result

def main():
    '''
    comments = open("E:\Py_Programs\week5\jd_comments.txt",\
        mode='r',encoding='utf-8').readlines()
    Tok = Tokenizer(comments, 'c', 0)
    '''
    #测试__init__函数，将结果字典输出到TestResult_1文件中
    '''
    TestResult_1 = open("E:\Py_Programs\week5\TestResult_1_w.txt",\
        mode='w',encoding='utf-8')
    for i in Tok.TokDict:
        TestResult_1.write("{} : {}\n".format(i, Tok.TokDict[i]))
    TestResult_1.close()
    '''
    #测试tokenize函数、encode函数、trim函数、decode函数
    #将各函数的结果输出到TestResult_2文件中
    '''
    TestResult_2 = open("E:\Py_Programs\week5\TestResult_2_c.txt",\
        mode='w',encoding='utf-8')
    test_sql_len = random.randint(50, 150)
    TestResult_2.write("本次测试指定的sql_len : %d\n" %test_sql_len)
    for i in range(10):
        test = random.randint(0,len(Tok.chars))
        TestResult_2.write("\n句子序号 :\t{}".format(test))
        Sen = Tok.chars[test]
        TestResult_2.write("\n原句子 :\t{}".format(Sen))
        LSen = Tok.tokenize(Sen)
        TestResult_2.write("分词(字)后的字符列表 :\t{}".format(LSen))
        Lnum = Tok.encode(LSen)
        TestResult_2.write("\n长短不一的数字列表 :\t{}".format(Lnum))
        Lnum_final = Tok.trim(Lnum, test_sql_len)
        TestResult_2.write("\n长短一致的数字列表 :\t{}".format(Lnum_final))
        initial_sen = ''.join(Tok.decode(Lnum_final))
        TestResult_2.write("\n还原得到的句子 :\t{}\n".format(initial_sen))
    TestResult_2.close()
    '''
    #测试encode_all函数，将结果绘图输出
    '''
    x = range(20, 150)
    y = []
    for i in x:
        y.append(len(Tok.encode_all(i)))
        print(i)
    plt.title("encode_all")
    plt.xlabel("sql_len")
    plt.ylabel("number_of_comments")
    plt.bar(x, y)
    plt.show()
    '''
    

if __name__ == '__main__':
    main()